#pragma once
#include "vector"
#include "vex.h"
#include "iostream"
using namespace std;

class ControllerEnhanced : public vex::controller {
public:
  //使用父类构造函数，支持两种:
  // ControllerEnhanced my_ctrl(primary); //主遥控
  // ControllerEnhanced my_ctrl(partner);//伙伴遥控
  using controller::controller;

  //遥控新增函数
public:
  bool any_button_pressing() {
    for (auto iter : vec_ptr_all_buttons)
      if (iter->pressing())
        return true;
    return false;
  }
  bool all_buttons_releasing() { return !any_button_pressing(); };

  /*
  ________________________________________________________________________________________________________
  //内部类定义：增强按键类(class button_enhanced）定义
  通过绑定到实际按键，并建立与其类成员同名的函数、变量实现。同时新增更多有用的函数。
  ________________________________________________________________________________________________________
  */
public:
  class button_enhanced {
    friend ControllerEnhanced; //打开访问private变量权限
  private:
    ControllerEnhanced *p_parent; //绑定的依附遥控
    const vex::controller::button &actual_button;  //绑定实际的按键
    bool additional_function_check_started=false;
  public:
    //绑定实际的事件
    const mevent &PRESSED;
    const mevent &RELEASED;

  public:
    //构造函数,将actual_button绑定到controller中的按键
    button_enhanced(const vex::controller::button &rb, ControllerEnhanced *parent)
        : actual_button(rb), PRESSED(rb.PRESSED), RELEASED(rb.RELEASED) {
      p_parent = parent;
      p_parent->vec_ptr_all_buttons.push_back(this); //保存本实例指针
    }

    //重定义与VEX库同名函数，隐藏库函数的原始定义
    void pressed(void (*callback)(void)) { actual_button.pressed(callback); }
    void released(void (*callback)(void)) { actual_button.released(callback); }
    bool pressing() { return actual_button.pressing(); }

    //////////////////////////////////////////////////////////////////////
  private:
    // 按键的各自情况判断
    // 1: 双击过：连续两次按下的时刻不超过设定时间。
    //然后松开或持续按下都可以。
    int double_click_max_interval = 250;
    bool double_clicked_status = false; //双击

    // 2: 三击过：连续三次按下的时刻不超过设定时间。
    //然后松开或持续按下都可以。
    int triple_click_max_interval = 250;
    bool triple_clicked_status = false; //三击，包含2个双击

    // 3: 短按过：按下时长不超过设定最大时长，并且已经松开
    int short_pressed_ever_max_time = 300; //短按着的置位的最长时间（ms）
    bool short_pressed_ever_status = false; //按键时间300，并松开

    // 4: 长按了：按下时长超过设定最小时长
    int long_pressed_latch_min_time = 600;
    bool long_pressed_latch_status = false; //按键时间大于最短时间

    // 5: 持续短按着：按下时长不超过最长时间，并依然按着。
    //超过设定时间则会为0，当持续再按，则会变成持续长按。
    int short_pressing_max_time = 300; //短按着的置位的最长时间（ms）
    bool short_pressing_status = false; //按键时间10~300，并正在按下

    // 6: 持续长按着：按下时长超过最短时间，并依然按着。
    int long_pressing_min_time = 600; //长按着置位的最短时间（ms）
    bool long_pressing_status = false; //按键时间大于最短时间，并正在按下

    //辅助变量
    long last_click_time = 0;       //按键前一次按下的时间
    long last_last_click_time = 0;  //按键前前一次按下的时间
    long btn_pressed_just_now = 0;  //按键上升沿判断标志
    long btn_released_just_now = 0; //按键下升沿判断标志
    bool btn_long_pressed_latch_set=false;//长按过置位


    //按键新增函数
  public:
    bool double_clicked(int double_click_max_interval = 250);
    bool triple_clicked(int triple_click_max_interval = 250);
    bool short_pressed_ever(int short_pressed_ever_max_time = 300);
    bool long_pressed_latch(int long_pressed_latch_min_time = 600);
    bool short_pressing(int short_pressing_max_time = 300);
    bool long_pressing(int long_pressing_min_time = 600);
  }; //内部类定义：加强按键类定义

public:
  //内部类会访问该vector，因此该vector定义必须在内部button_enhanced变量定义之前，否则会出现莫名bug
  //遥控中保存的按键指针,用以保存本遥控的各个按键
  vector<button_enhanced *> vec_ptr_all_buttons;
  bool pressing_status_monitoring_on = false;
  void buttons_status_monitoring_start_once();
  static void buttons_status_monitoring_routine(void *p_this_controller);

  //内部按键变量
  //建立与VEX库同名的button_enhanced按键,用来屏蔽controller::button类型的按键
  //注意：以下按键定义需要以 ButtonL1为第一个！
  button_enhanced ButtonL1 = button_enhanced(controller::ButtonL1, this);
  button_enhanced ButtonL2 = button_enhanced(controller::ButtonL2, this);
  button_enhanced ButtonR1 = button_enhanced(controller::ButtonR1, this);
  button_enhanced ButtonR2 = button_enhanced(controller::ButtonR2, this);

  button_enhanced ButtonUp = button_enhanced(controller::ButtonUp, this);
  button_enhanced ButtonDown = button_enhanced(controller::ButtonDown, this);
  button_enhanced ButtonLeft = button_enhanced(controller::ButtonLeft, this);
  button_enhanced ButtonRight = button_enhanced(controller::ButtonRight, this);

  button_enhanced ButtonX = button_enhanced(controller::ButtonX, this);
  button_enhanced ButtonB = button_enhanced(controller::ButtonB, this);
  button_enhanced ButtonY = button_enhanced(controller::ButtonY, this);
  button_enhanced ButtonA = button_enhanced(controller::ButtonA, this);
  //________________________________________________________________________________________________________
};
